package pl.edu.mimuw.mas.agent;

import jade.content.ContentManager;
import jade.content.lang.Codec;
import jade.content.lang.Codec.CodecException;
import jade.content.lang.sl.SLCodec;
import jade.content.onto.Ontology;
import jade.content.onto.OntologyException;
import jade.content.onto.UngroundedException;
import jade.content.onto.basic.Action;
import jade.core.Agent;
import jade.domain.DFService;
import jade.lang.acl.ACLMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pl.edu.mimuw.mas.agent.behaviour.DFRegisterBehaviour;
import pl.edu.mimuw.mas.agent.behaviour.ServerBehaviour;
import pl.edu.mimuw.mas.agent.gui.ILogBE;
import pl.edu.mimuw.mas.agent.gui.LogPanel;
import pl.edu.mimuw.mas.gui.ITabContener;
import pl.edu.mimuw.mas.ontology.VisualizationCoreOntology;
import pl.edu.mimuw.mas.ontology.concept.LogEntry;

/**
 * Agent logujący zdarzenia - logowanie 'biznesowe'.
 */
public class LogAgent extends Agent implements ILogBE {
	private static final long serialVersionUID = 7475446867589431199L;
	
	public static final String SERVICE_TYPE = "logging-service";	
	public static final String TAB_TITLE = "Logowanie";	

	public static final int ARGC = 2;
	
	private final Codec codec = new SLCodec();
	private final Ontology ontology = VisualizationCoreOntology.getInstance();

	private boolean active;
	
	private ITabContener mainWindow;
	private LogPanel panel;
	
	private final Logger log = LoggerFactory.getLogger(getClass());
	
	protected void setup() {
		log.info("{} : aktywny", getName());
		
		if(!setParameters()) {
			return;
		}
		
		// Rejestruje ontologie do automatycznej serializacji i deserializacji SL
		getContentManager().registerLanguage(codec);
		getContentManager().registerOntology(ontology);	
		log.info(getName() + ": ontologie zarejestrowane");
	
		// Uruchamia gui
		panel = new LogPanel(this);
		mainWindow.addTab(this, TAB_TITLE, panel);
		log.info("{} : logowanie uruchomione", getName());
		
		// Zachowania
		addBehaviour(new DFRegisterBehaviour(this, SERVICE_TYPE, VisualizationCoreOntology.ONTOLOGY_NAME));
		addBehaviour(new ServerBehaviour(this) {
			private static final long serialVersionUID = 7677529063951668524L;

			public boolean doAction(ACLMessage msg, ACLMessage reply) throws UngroundedException, CodecException, OntologyException {
				// Deserializacja SL
				ContentManager cm = myAgent.getContentManager();
				Action act = (Action) cm.extractContent(msg);
				LogEntry le = (LogEntry) act.getAction();

				if (le != null) {
					if(active) {
						panel.addLogEntry(le);
					}
				}
				
				return false;
			}
		});
	}
	
	protected void takeDown() {
		log.info("{} : papa", getName());
		try {
			DFService.deregister(this);
		} catch (Exception e) {
			log.debug("Kłopoty z wyrejstrowywaniem", e);
		}
	}
	
	private boolean setParameters() {
		try {
			Object[] obj = getArguments();
			
			mainWindow = (ITabContener) obj[0];
			active = (Boolean) obj[1];
			
			if (obj.length > ARGC) {
				log.warn("{} : część parametrów zostanie zignorowana", getName());
			}
			
			return true;

		} catch (ClassCastException e) {
			log.error("{} : niespodziewany typ", getName());
			doDelete();
		} catch (IndexOutOfBoundsException e) {
			log.error("{} : pusty parametr", getName());
			doDelete();
		} catch (NullPointerException e) {
			log.error("{} : pusty parametr", getName());
			doDelete();
		}
		
		return false;
	}
	
	//
	// ILogBE
	//

	public boolean isActive() {
		return this.active;
	}
	
	public void toogleActivity() {
		this.active = !this.active;
	}	
}
